package com.example.up;

import android.util.Log;

import java.io.File;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Created by yinghao on 2017/2/17.
 * Email：yhaowa@outlook.com
 * <p>
 * 一个分块池对应一个文件，要限制分块池的数量防止OOM
 */

class BlockPool {

    private static final int BLOCK_NUM = 1;
    private static final String TAG = "BlockPool";

    private static final double[] BLOCK_SIZE = new double[]{
            0.5 * 1024 * 1024, 1024 * 1024, 2 * 1024 * 1024, 3 * 1024 * 1024, 4 * 1024 * 1024
    };

    private Queue<Block> mFileQueue = new LinkedList<>();
    private final AccessThread mAccessThread = new AccessThread();

    private FileAccess mFileAccess;


    BlockPool(File file) {
        mFileAccess = new FileAccess(file);
        mAccessThread.start();
    }

    private long totalTime;

    Block take() {
        long time = System.currentTimeMillis();
        synchronized (mAccessThread) {
            Block block = mFileQueue.poll();
            if (block == null) {
                //若take先抢到锁
                block = addBlock() ? mFileQueue.poll() : null;
            }
            mAccessThread.notify();
            totalTime += System.currentTimeMillis() - time;
            if (block == null) {
                Log.d(TAG, "取文件时实际等待的总时间=" + totalTime);
                totalTime = 0;
            }
            return block;
        }
    }


    /**
     * 1. 自动补全BLOCK_NUM个File
     * 2. 当前文件数量小于BLOCK_NUM时，唤醒
     * 3. 当前文件数量等于BLOCK_NUM时，阻塞
     */
    private class AccessThread extends Thread {
        @Override
        public void run() {
            synchronized (mAccessThread) {
                while (true) {
                    while (mFileQueue.size() < BLOCK_NUM) {
                        if (!addBlock()) {
                            return;
                        }
                    }
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        Log.e(TAG, "InterruptedException:" + e.getMessage());
                    }
                }
            }
        }
    }

    private long totalTime2;

    private boolean addBlock() {
        long time = System.currentTimeMillis();
        int blockSize = BlockSize.getBlockSize();
        File file = mFileAccess.getNextBlockFile(blockSize);
        if (file == null) {
            Log.d(TAG, "addBlock: 分割文件总时间="+totalTime2);
            totalTime2 = 0;
            return false;
        }
        mFileQueue.add(new Block(file, mFileAccess.mOffset - blockSize, blockSize));
        totalTime2 += System.currentTimeMillis() - time;
        return true;
    }


}
